﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;

namespace EasyPath
{
    class PathManager
    {
        private const string PathVariableName = "Path";
        private const string PathDelimiter = ";";

        private static readonly char[] PathDelimiterChars = PathDelimiter.ToCharArray();

        private readonly EnvironmentVariableTarget _target;
        private string _original;
        private Dictionary<string, DirectoryInfo> _pathMap;
        private SortableBindingList<string> _pathList;
        
        public PathManager(EnvironmentVariableTarget target)
        {
            _target = target;
            _original = Environment.GetEnvironmentVariable(PathVariableName, _target);
            _pathMap = new Dictionary<string, DirectoryInfo>();
            _pathList = new SortableBindingList<string>();
            Reset();
        }

        public IEnumerable<string> GetPaths()
        {
            return _pathMap.Keys;
        }

        public bool AddPath(string path)
        {
            if (!_pathMap.ContainsKey(path))
            {
                _pathList.Add(path);
                _pathMap.Add(path, new DirectoryInfo(path));
                return true;
            }

            return false;
        }

        public bool IncludesPath(string path)
        {
            return _pathMap.ContainsKey(path);
        }

        public bool RemovePath(string path)
        {
            if (_pathMap.Remove(path))
            {
                _pathList.Remove(path);
                return true;
            }

            return false;
        }

        public void Save()
        {
            string current = Environment.GetEnvironmentVariable(PathVariableName, _target);
            if (current != _original)
            {
                throw new InvalidOperationException(string.Format("The PATH variable has changed since this {0} instance was created.", GetType()));
            }

            string value = ToString();
            Environment.SetEnvironmentVariable(PathVariableName, value, _target);
        }

        public void Reset()
        {
            _pathMap.Clear();
            _pathList.Clear();

            string[] paths = _original.Split(PathDelimiterChars);
            for (int i = 0; i < paths.Length; ++i)
            {
                AddPath(paths[i]);
            }
        }

        public void SortPaths()
        {
            _pathList.Sort();
        }

        public void ReversePaths()
        {
            _pathList.Reverse();
        }

        public override string ToString()
        {
            string result = string.Format("{0} {1}", _target, string.Join(PathDelimiter, _pathList));
            return result;
        }

        internal void SetAsDataSource(ListControl listControl)
        {
            listControl.DataSource = _pathList;
        }
    }
}
